#include "opengl.h"

#include <math.h>

static GLuint filter;                      
static GLuint fogMode[]= { GL_EXP, GL_EXP2, GL_LINEAR };
static GLuint fogfilter= 2; 
static GLfloat fogColor[4]= {0.2f, 0.3f, 0.5f, 1.0f};  

void OpenGL_Init(int width,int height)
{
	glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
	gluPerspective(70,(double)SDL_GetVideoInfo()->current_w / SDL_GetVideoInfo()->current_h,1,1000);
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
	glMatrixMode(GL_MODELVIEW);
    glEnable(GL_DEPTH_TEST);
	glEnable(GL_LIGHTING);
	glEnable(GL_TEXTURE_2D);
	glEnable(GL_CULL_FACE);
	 /* initialisation de glew */
    glewInit();
	glFogi(GL_FOG_MODE, fogMode[fogfilter]);       
	glFogfv(GL_FOG_COLOR, fogColor);       
	glFogf(GL_FOG_DENSITY, 0.15f);         
	glHint(GL_FOG_HINT, GL_DONT_CARE);      
	glFogf(GL_FOG_START, 1.0f);             
	glFogf(GL_FOG_END, 1000.0f);     
	glEnable(GL_FOG);              
}

void OpenGL_DrawMode(int mode)
{
	if (mode == 1)
		glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
	if (mode == 2)
		glPolygonMode( GL_FRONT, GL_FILL);
}

/*
void OpenGL_DrawSprite(const Sprite* sprite)
{
	glBlendFunc(GL_SRC_ALPHA,GL_ONE);
    glEnable(GL_BLEND);
	glDisable(GL_LIGHTING);
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, sprite->textureId);
	glPushMatrix();
		glTranslatef(sprite->position.x,sprite->position.y,sprite->position.z);
		glRotatef(-sprite->theta,0,1,0);
		glRotatef(sprite->phi,0,0,1);
		glColor4ub(sprite->color.r,sprite->color.g,sprite->color.b,sprite->color.a);
		glBegin(GL_QUADS);
				glTexCoord2f(sprite->y, sprite->x); glVertex3f(0,-1, -1);
				glTexCoord2f(sprite->y + sprite->height,sprite->x); glVertex3f( 0,-1, 1);
				glTexCoord2f(sprite->y + sprite->height, sprite->x + sprite->width); glVertex3f( 0, 1, 1);
				glTexCoord2f(sprite->y, sprite->x + sprite->width); glVertex3f( 0, 1, -1);
		glEnd();
	glPopMatrix();
}

void OpenGL_DrawSprites(const Sprite* sprite, const Vector3f** positions, int height)
{
	int i;
	glBlendFunc(GL_SRC_ALPHA,GL_ONE);
    glEnable(GL_BLEND);
	glDisable(GL_LIGHTING);
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, sprite->textureId);
	glColor4ub(sprite->color.r,sprite->color.g,sprite->color.b,sprite->color.a);
	for(i = 0; i < height; i++)
	{
	    glPushMatrix();
			glTranslatef(sprite->position.x,sprite->position.y,sprite->position.z);
			glRotatef(-sprite->theta,0,1,0);
			glRotatef(sprite->phi,0,0,1);
			glBegin(GL_QUADS);
				glTexCoord2f(sprite->y, sprite->x); glVertex3f(0,-1, -1);
				glTexCoord2f(sprite->y + sprite->height,sprite->x); glVertex3f( 0,-1, 1);
				glTexCoord2f(sprite->y + sprite->height, sprite->x + sprite->width); glVertex3f( 0, 1, 1);
				glTexCoord2f(sprite->y, sprite->x + sprite->width); glVertex3f( 0, 1, -1);
			glEnd();
		glPopMatrix();
	}
}*/

void OpenGL_InitFrame()
{
	glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
}

void OpenGL_EndFrame()
{
	glFlush();
}

void OpenGL_DrawLines(const Vector3f* dots, const Color* colors, int* lineWidth, int height, LINES_DRAW_MODE lineDrawMode)
{
	int i;
	glPushAttrib(GL_ALL_ATTRIB_BITS);

	glDisable(GL_LIGHTING);
    glDisable(GL_TEXTURE_2D);
	glEnable(GL_BLEND);
	glEnable(GL_LINE_SMOOTH);
	glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

	glPushMatrix();
	glBegin(GL_LINES);
	switch(lineDrawMode)
	{
	case LINES_DRAW_MODE_CONTIGUOUS:
		for (i = 0; i < (height - 1); i++)
		{
			glLineWidth(lineWidth[i]);
			glColor4ub(colors[i].r,colors[i].g,colors[i].b,colors[i].a);
			glVertex3f(dots[i].x,dots[i].y,dots[i].z);
			glVertex3f(dots[i+1].x,dots[i+1].y,dots[i+1].z);
		}
		break;
	case LINES_DRAW_MODE_SEPARATE:
		for (i = 0; i < height; i++)
		{
			glLineWidth(lineWidth[i]);
			glColor4ub(colors[i].r,colors[i].g,colors[i].b,colors[i].a);
			glVertex3f(dots[i*2].x,dots[i*2].y,dots[i*2].z);
			glVertex3f(dots[i*2+1].x,dots[i*2+1].y,dots[i*2+1].z);
		}
		break;
	}
	glEnd();

    glPopMatrix();

    glPopAttrib();
}

void OpenGL_DrawLine(const Vector3f* dot1,const Vector3f* dot2, const Color* color, int lineWidth)
{
	Vector3f dots[2];
	dots[0] = *dot1;
	dots[1] = *dot2;
	OpenGL_DrawLines(dots,color,&lineWidth,1,LINES_DRAW_MODE_SEPARATE);
}

void OpenGL_LookAt(const Vector3f* position, const Vector3f* target)
{
	gluLookAt(position->x,position->y,position->z,
              target->x,target->y,target->z,
              0,1,0);
}
